#include "GY_CategoryTree.h"
#include <QMessageBox>
#include <QDebug>
#include <QMenu>
#include <QInputDialog>
#include <QtSql/QSqlError>
#include <QtSql/QSqlRecord>
#include <QtSql/QSqlField>
#include <QJsonArray>
#include <QJsonObject>
#include <QDragEnterEvent>
#include <QMimeData>
#include "GY_CategoryTreeSetValDlg.h"
GY_CategoryTree::GY_CategoryTree(QWidget *parent) : QTreeWidget(parent)
{
    //初始设置
    setEditTriggers(QAbstractItemView::NoEditTriggers);
    setHeaderHidden(true);
    setDragEnabled(true);
    setDragDropMode(QAbstractItemView::InternalMove);  //拖拽调整分类，父类无法移动到子类里
    initMenu();
}

void GY_CategoryTree::setDbTableName(const QString &value)
{
    dbTableName = value.trimmed();
}

void GY_CategoryTree::setPQuery(QSqlQuery *value)
{
    pQuery = value;
}

QVector<QVector<QVariant>> GY_CategoryTree::queryData(QString sqlCmd)
{
    QVector<QVariant> tempValue;
    QVector<QVector<QVariant>> result;
    if(!pQuery->exec(sqlCmd))  //
    {
        qDebug()<<"query failed."<<endl;
        qDebug()<<"error: "<<pQuery->lastError().text();
    }
    else
    {
        int columnCount = pQuery->record().count(); //获取数据表的列数
        while(pQuery->next()){
            for(int i=0; i<columnCount; i++){
                tempValue.append(pQuery->value(i));
            }
            result.append(tempValue);
            tempValue.clear();
        }
    }
    return result;
}

bool GY_CategoryTree::insertData(QString sqlCmd)
{
    if(!pQuery->exec(sqlCmd))
    {
        qDebug()<<"query failed: "<< pQuery->lastError().text() <<endl;
        return false;
    }
    else
    {
        qDebug()<<"insert success."<<endl;
        return true;
    }
}

bool GY_CategoryTree::updateData(QString sqlCmd)
{
    qDebug()<<"sqlcmd= "<<sqlCmd;
    if(!pQuery->exec(sqlCmd))
    {
        qDebug()<<"update failed."<< pQuery->lastError().text() <<endl;
        return false;
    }
    else
    {
        qDebug()<<"update success."<<endl;
        return true;
    }
}

bool GY_CategoryTree::deleteData(QString sqlCmd)
{
    if(!pQuery->exec(sqlCmd))
    {
        qDebug()<<"delete failed."<<pQuery->lastError().text() <<endl;
        return false;
    }
    else
    {
        qDebug()<<"delete Success."<<endl;
        return true;
    }
}

void GY_CategoryTree::initTree()
{
    if(!pQuery){
        QMessageBox::information(this,"提示","未设置数据库操作对象");
        return;
    }

    if(dbTableName.isEmpty()){
        QMessageBox::information(this,"提示","未设置数据库表");
        return;
    }

    QString strSql = QString("select * from %1 order by id asc;").arg(dbTableName);
    QVector<QVector<QVariant>> result = queryData(strSql);
    int columnCount = pQuery->record().count(); //获取数据表的列数
    if(3 > columnCount ){
        QMessageBox::information(this,"提示","表字段须至少满足前3个字段");
        return;
    }

    for (int i = 0; i < columnCount; ++i) {
        QString fieldName = pQuery->record().fieldName(i);
        columns.append(fieldName);
    }

    setColumnCount(columnCount);
    for(int i = 1; i < columnCount; ++i){
        hideColumn(i);
    }




    //填充数据显示
    for (QVector<QVariant> row : result) {
        //默认列顺序
        QString id = row[0].toString();
        QString pid = row[1].toString();
        QString name = row[2].toString();
        QStringList list({name,id});  //树的列顺序
        for(int i = 3; i < row.count(); ++i){
            list.push_back(row[i].toString());
        }

        if("0" == pid){  //是顶级分类
            QTreeWidgetItem* group = new QTreeWidgetItem(this,list);
            addTopLevelItem(group);
        }
        else{  //不是顶级分类
            //查找上级分类
            QTreeWidgetItemIterator itor(this);
            while (*itor) {
                if(pid == (*itor)->text(TreeColumns::id)){  //id相同
                    QTreeWidgetItem* group = new QTreeWidgetItem(*itor,list);
                    (*itor)->addChild(group);
                    break;
                }
                ++itor;
            }

        }
    }
}

void GY_CategoryTree::initMenu()
{
    setContextMenuPolicy(Qt::CustomContextMenu);
    connect(this, &GY_CategoryTree::customContextMenuRequested, this, &GY_CategoryTree::customContextMenu);
    pMenu = new QMenu(this);

    pAdd = new QAction("添加分类", pMenu);
    pEdit = new QAction("编辑分类", pMenu);
    pDel = new QAction("删除分类", pMenu);

    pMenu->addAction(pAdd);
    pMenu->addAction(pEdit);
    pMenu->addAction(pDel);

    connect(pAdd, &QAction::triggered, this, &GY_CategoryTree::add);
    connect(pEdit, &QAction::triggered, this, &GY_CategoryTree::edt);
    connect(pDel, &QAction::triggered, this, &GY_CategoryTree::del);

}

void GY_CategoryTree::customContextMenu(const QPoint &pos)
{
    Q_UNUSED(pos)

    pAdd->setVisible(true);

    QModelIndex idx = currentIndex();

    if(!idx.isValid()){
        pEdit->setVisible(false);
        pDel->setVisible(false);
    }
    else{
        pEdit->setVisible(true);
        pDel->setVisible(true);

    }

    pMenu->exec(cursor().pos());
}

void GY_CategoryTree::add()
{
    if(!pQuery){
        QMessageBox::information(this,"提示","未设置数据库操作对象");
        return;
    }

    if(dbTableName.isEmpty()){
        QMessageBox::information(this,"提示","未设置数据库表");
        return;
    }

    QJsonArray columnsValue;
    for(int i = 0; i < columns.count(); ++i){
        QJsonObject kv;
        kv["column"] = columns[i];
        if("pid" == kv["column"].toString()){  //预设置pid为当前的id
            if(currentItem()){
                kv["value"] = currentItem()->text(id);
            }
            else{
                kv["value"] = "";
            }
        }
        else{
            kv["value"] = "";
        }
        columnsValue.push_back(kv);
    }


    QString strSql = QString("select id, name, pid from %1 order by id asc;").arg(dbTableName);
    QVector<QVector<QVariant>> result = queryData(strSql);

    GY_CategoryTreeSetValDlg dlg(columnsValue, result);
    if(QDialog::Accepted == dlg.exec()){
        columnsValue = dlg.getColumnsValue();

        //构造设置的列和值
        QString strColumns;
        QString strValues;
        for(int i = 0; i < columnsValue.size(); ++i){
            QJsonObject kv = columnsValue[i].toObject();
            if(i){
                strColumns.append(" , ");
                strValues.append(" , ");
            }

            strColumns.append(kv["column"].toString());
            if("id" != kv["column"].toString() && "pid" != kv["column"].toString()){
                strValues.append("'");
            }

            strValues.append(kv["value"].toString());

            if("id" != kv["column"].toString() && "pid" != kv["column"].toString()){
                strValues.append("'");
            }

        }

        strSql = QString("insert into %1(%2) values(%3);").arg(dbTableName).arg(strColumns).arg(strValues);

        if(insertData(strSql)){
            //更新界面
            strSql = QString("select max(id) from %1;").arg(dbTableName);
            result = queryData(strSql);
            QString id = result[0][0].toString();
            //默认顺序取值
            QString pid = columnsValue[0].toObject()["value"].toString();
            QString name = columnsValue[1].toObject()["value"].toString();
            QStringList list({name,id});  //树的列顺序
            for(int i = 2; i < columnsValue.count(); ++i){
                list.push_back(columnsValue[i].toObject()["value"].toString());
            }

            if("0" == pid){  //顶级分类
                QTreeWidgetItem* group = new QTreeWidgetItem(this,list);
                addTopLevelItem(group);
            }
            else{  //不是顶级分类
                //查找上级分类
                QTreeWidgetItemIterator itor(this);
                while (*itor) {
                    if(pid == (*itor)->text(TreeColumns::id)){  //id相同
                        QTreeWidgetItem* group = new QTreeWidgetItem(*itor,list);
                        (*itor)->addChild(group);
                        this->expandItem(*itor);
                        break;
                    }
                    ++itor;
                }

            }
        }
        else{
            QMessageBox::information(this,"提示","添加分类到数据库失败");
        }

    }

}

void GY_CategoryTree::edt()
{
    if(!pQuery){
        QMessageBox::information(this,"提示","未设置数据库操作对象");
        return;
    }

    if(dbTableName.isEmpty()){
        QMessageBox::information(this,"提示","未设置数据库表");
        return;
    }

    QString id = currentItem()->text(TreeColumns::id);

    QJsonArray columnsValue;
    for(int i = 0; i < columns.count(); ++i){
        QJsonObject kv;
        kv["column"] = columns[i];
        if("pid" == kv["column"].toString()){
            continue;  //编辑分类不能用于pid
        }
        else if("name" == kv["column"].toString()){
            kv["value"] = currentItem()->text(name);
        }
        else{
            kv["value"] = currentItem()->text(i);  //id列在设置窗口会被忽略
        }
        columnsValue.push_back(kv);
    }

    QString strSql = QString("select id, name, pid from %1 order by id asc;").arg(dbTableName);
    QVector<QVector<QVariant>> result = queryData(strSql);

    GY_CategoryTreeSetValDlg dlg(columnsValue, result);
    if(QDialog::Accepted == dlg.exec()){
        columnsValue = dlg.getColumnsValue();

        //构造设置的列和值
        QString strColumnValues;
        for(int i = 0; i < columnsValue.size(); ++i){
            QJsonObject kv = columnsValue[i].toObject();
            if(i){
                strColumnValues.append(" , ");
            }

            strColumnValues.append(kv["column"].toString()).append(" = ");

            if("id" != kv["column"].toString() && "pid" != kv["column"].toString()){
                strColumnValues.append("'");
            }
            strColumnValues.append(kv["value"].toString());
            if("id" != kv["column"].toString() && "pid" != kv["column"].toString()){
                strColumnValues.append("'");
            }

        }

        strSql = QString("update %1 set %2 where id = %3;").arg(dbTableName).arg(strColumnValues).arg(id);

        if(updateData(strSql)){
            //更新界面
            for(int i = 0; i < columnCount(); ++i){
                if(TreeColumns::name == i){
                    //默认顺序取值
                    QString name = columnsValue[0].toObject()["value"].toString();
                    currentItem()->setText(TreeColumns::name,name);
                }
                else if(TreeColumns::id == i){
                    continue;
                }
                else{
                     QString text = columnsValue[i-1].toObject()["value"].toString();
                     currentItem()->setText(i,text);
                }


            }

        }
        else{
            QMessageBox::information(this,"提示","添加分类到数据库失败");
        }

    }

}

void GY_CategoryTree::del()
{
    if(QMessageBox::No == QMessageBox::question(this,"提示","确定删除此分类")){
        return;
    }

    if(!pQuery){
        QMessageBox::information(this,"提示","未设置数据库操作对象");
        return;
    }

    if(dbTableName.isEmpty()){
        QMessageBox::information(this,"提示","未设置数据库表");
        return;
    }

    int id = currentItem()->text(TreeColumns::id).toInt();

    //找到树节点下面所有分类节点
    QVector<int> groupIds;
    groupIds.push_back(id);

    QVector<QTreeWidgetItem * > children = AllChildrenItem(currentItem());
    for(QTreeWidgetItem * child : children){
        groupIds.push_back(child->text(TreeColumns::id).toInt());
    }

    QString strSql;
    strSql = QString("delete from %1 where ").arg(dbTableName);
    for(int i = 0; i < groupIds.size(); ++i){
        if(i){
            strSql.append(" or ");
        }
        QString condition = QString(" id = %1 ").arg(groupIds[i]);
        strSql.append(condition);
    }
    strSql.append(";");

    if(deleteData(strSql)){

        model()->removeRow(currentIndex().row(),currentIndex().parent());
    }
    else{
        QMessageBox::information(this,"提示","删除分类失败");
    }

}

QVector<QTreeWidgetItem * > GY_CategoryTree::AllChildrenItem(QTreeWidgetItem * parent){
    QVector<QTreeWidgetItem * > items;

    for(int i = 0; i < parent->childCount(); ++i){
        items.push_back(parent->child(i));
        QVector<QTreeWidgetItem * > children = AllChildrenItem(parent->child(i));
        for(QTreeWidgetItem * child : children){
            items.push_back(child);
        }
    }
    return items;
}

void GY_CategoryTree::dragEnterEvent(QDragEnterEvent * event)
{
    event->acceptProposedAction();

    pItemToMove = currentItem();
    pItemParent = pItemToMove->parent();
}

void GY_CategoryTree::dragMoveEvent(QDragMoveEvent * event)
{
    event->acceptProposedAction();
}

void GY_CategoryTree::dropEvent(QDropEvent * event)
{
    QTreeWidget::dropEvent(event);  //must

    //保存移动项的修改到数据库
    if(pItemToMove->parent() != pItemParent){  //移动且有修改
        QString pid;
        if(pItemToMove->parent()){
//            qDebug() <<"\n" << pItemToMove->parent()->text(0) <<"\n";
            pid = pItemToMove->parent()->text(TreeColumns::id);
            expandItem(pItemToMove);
        }
        else{
//            qDebug() <<"\n move to top level\n";
            pid = "0";
        }


        QString id = pItemToMove->text(TreeColumns::id);
        QString strSql = QString("update %1 set pid = %2 where id = %3;").arg(dbTableName).arg(pid).arg(id);

        if(!updateData(strSql)){
            QMessageBox::information(this,"提示","保存数据库失败，还原移动");
            //还原移动
            QStringList list;
            for(int i = 0; i < columnCount(); ++i){
                list.append(pItemToMove->text(i));
            }
            QTreeWidgetItem * pItem = new QTreeWidgetItem(pItemParent,list);
            if(pItemParent){
                pItemParent->addChild(pItem);
            }
            else{
                addTopLevelItem(pItem);
            }

            if(pItemToMove->parent()){
                pItemToMove->parent()->removeChild(pItemToMove);
            }
            else{
                this->invisibleRootItem()->removeChild(pItemToMove);
            }

        }
    }
}
